module rad_types_mod

  use const_mod
  use phys_types_mod

  implicit none

  type rad_band_type

  end type rad_band_type

  type rad_input_type
    integer :: ncol = 0
    integer :: nlev = 0
    real(r8) S0                                         ! Broadband solar irradiance (W m-2)
    real(r8), allocatable, dimension(:,:) :: mu0        ! Cosine of solar zenith angle
    real(r8), allocatable, dimension(:,:) :: tau        ! Optical depth (1)
    real(r8), allocatable, dimension(:,:) :: alb_sw_dir ! Shortwave albedo to direct radiation
    real(r8), allocatable, dimension(:,:) :: alb_sw_dif ! Shortwave albedo to diffuse radiation
    real(r8), allocatable, dimension(:,:) :: emis_lw    ! Longwave emissivity
    type(phys_state_type), pointer :: atm               ! Atmosphere profiles
  contains
    procedure :: init  => rad_input_init
    procedure :: clear => rad_input_clear
    final :: rad_input_final
  end type rad_input_type

  type rad_output_type
    integer :: ncol = 0
    integer :: nlev = 0
    real(r8), allocatable, dimension(:,:) :: fup_sw     ! Upward flux (W m-2)
    real(r8), allocatable, dimension(:,:) :: fup_sw_clr ! Upward clear-sky flux (W m-2)
    real(r8), allocatable, dimension(:,:) :: fdn_sw     ! Downward flux (W m-2)
    real(r8), allocatable, dimension(:,:) :: fdn_sw_clr ! Downward clear-sky flux (W m-2)
    real(r8), allocatable, dimension(:,:) :: fup_lw     ! Upward flux (W m-2)
    real(r8), allocatable, dimension(:,:) :: fup_lw_clr ! Upward clear-sky flux (W m-2)
    real(r8), allocatable, dimension(:,:) :: fdn_lw     ! Downward flux (W m-2)
    real(r8), allocatable, dimension(:,:) :: fdn_lw_clr ! Downward clear-sky flux (W m-2)
  contains
    procedure :: init  => rad_output_init
    procedure :: clear => rad_output_clear
    final :: rad_output_final
  end type rad_output_type

  type rad_coef_type

  end type rad_coef_type

contains

  subroutine rad_input_init(this, ncol, nlev)

    class(rad_input_type), intent(inout) :: this
    integer, intent(in) :: ncol
    integer, intent(in) :: nlev

    call this%clear()

    this%ncol = ncol
    this%nlev = nlev
    allocate(this%mu0(nlev,ncol))
    allocate(this%tau(nlev,ncol))
    allocate(this%t  (nlev,ncol))

  end subroutine rad_input_init

  subroutine rad_input_clear(this)

    class(rad_input_type), intent(inout) :: this

    if (allocated(this%mu0)) deallocate(this%mu0)
    if (allocated(this%tau)) deallocate(this%tau)
    if (allocated(this%t  )) deallocate(this%t  )

  end subroutine rad_input_clear

  subroutine rad_input_final(this)

    type(rad_input_type), intent(inout) :: this

    call this%clear()

  end subroutine rad_input_final

  subroutine rad_output_init(this, ncol, nlev)

    class(rad_output_type), intent(inout) :: this
    integer, intent(in) :: ncol
    integer, intent(in) :: nlev

    call this%clear()

    this%ncol = ncol
    this%nlev = nlev
    allocate(this%fup(nlev+1,ncol))
    allocate(this%fdn(nlev+1,ncol))

  end subroutine rad_output_init

  subroutine rad_output_clear(this)

    class(rad_output_type), intent(inout) :: this

    if (allocated(this%fup)) deallocate(this%fup)
    if (allocated(this%fdn)) deallocate(this%fdn)

  end subroutine rad_output_clear

  subroutine rad_output_final(this)

    type(rad_output_type), intent(inout) :: this

    call this%clear()

  end subroutine rad_output_final

end module rad_types_mod
